package com.wan.net.rpc;

import com.sun.istack.internal.NotNull;
import com.wan.net.rpc.registry.Registry;
import com.wan.net.rpc.service.RpcService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wwh
 * @date 2022/6/20 18:05
 */
public class RpcManager {
    /** rpc所有服务server */
    private static final Map<String,RpcServer> RPC_SERVER_MAP = new ConcurrentHashMap<>(1);
    /** 服务注册的临时存放 */
    private static final Map<String, List<RpcService>> tempRegistryServices = new HashMap<>();
    /** 注册中心 */
    private static Registry registry = Registry.LOCAL;

    protected synchronized static void addRpcServer(RpcServer rpcServer){
        if(RPC_SERVER_MAP.containsKey(rpcServer.getName())){
            throw new RuntimeException("rpcServer名称不能重复:" + rpcServer.getName());
        }
        RPC_SERVER_MAP.put(rpcServer.getName(),rpcServer);
        List<RpcService> rpcServices = tempRegistryServices.get(rpcServer.getName());
        if(rpcServices != null && rpcServices.size() > 0){
            for (RpcService rpcService : rpcServices) {
                rpcService.copyAt(rpcServer.getRpcService());
                rpcServer.addSubService(rpcService);
                registry.registry(rpcService);
            }
        }
    }

    /**
     * 注册服务
     * @param bindName 绑定的server名称
     * @param rpcService 服务
     */
    public synchronized static void registryService(String bindName,RpcService rpcService){
        RpcServer bindServer = RPC_SERVER_MAP.get(bindName);
        if(bindServer != null){
            rpcService.copyAt(bindServer.getRpcService());
            bindServer.addSubService(rpcService);
            registry.registry(rpcService);
            return;
        }
        //服务还未启动，放到临时区等待
        tempRegistryServices.computeIfAbsent(bindName,l->new ArrayList<>()).add(rpcService);
    }

    public static Registry getRegistry() {
        return registry;
    }

    public static void setRegistry(@NotNull Registry registry) {
        if(registry == null){
            throw new NullPointerException("[rpc]注册中心不允许设置为空");
        }
        RpcManager.registry = registry;
    }
}
